package net.zoneland.knowledge.filters;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

import net.zoneland.knowledge.dao.PerformanceMonitorMapper;
import net.zoneland.knowledge.service.AuthService;
import net.zoneland.knowledge.service.LoginLogService;
import net.zoneland.knowledge.service.PartyService;
import net.zoneland.knowledge.service.ResourceService;
import net.zoneland.knowledge.service.RoleService;
import net.zoneland.knowledge.service.UserService;
import net.zoneland.knowledge.service.PurviewService;

/**
 * Filter配置.
 *
 * @author: bcc
 * 2021/5/28
 */
@Configuration
public class FilterConfig {

    /**
     * token Filter 顺序.
     */
    private static final int TOKEN_FILTER_ORDER = 20;

    /**
     * security Filter 顺序.
     */
    private static final int SECURITY_FILTER_ORDER = 30;

    /**
     * monitor Filter 顺序.
     * 这个过滤器放在SecurityFilter之后，为了能获取用户id,
     * 这么做的副作用：这个SecurityFilter的耗时没有监控到，暂时先这样
     */
    private static final int MONITOR_FILTER_ORDER = 40;

    @Value("${mx.sso.getUserUrl}")
    private String getUserUrl;

    @Value("${mx.sso.accessToken}")
    private String accessToken;

    @Value("${demo:false}")
    private boolean demo;

    /**
     * 注册token过滤器.
     * @param authService 认证服务
     * @param userService 人员信息服务
     * @return FilterRegistrationBean 过滤器
     */
    @Bean
    public FilterRegistrationBean<TokenFilter> registerTokenFilter(final AuthService authService, final UserService userService) {
        final FilterRegistrationBean<TokenFilter> bean = new FilterRegistrationBean<>();
        bean.setOrder(TOKEN_FILTER_ORDER);
        final TokenFilter tokenFilter = new TokenFilter();
        tokenFilter.setUserService(userService);
        tokenFilter.setAuthService(authService);
        bean.setFilter(tokenFilter);
        bean.addUrlPatterns("/*");
        return bean;
    }

    /**
     * 注册安全认证过滤器.
     * @param resourceService 资源服务
     * @param roleService 角色相关服务
     * @param restTemplate restTemplate
     * @param authService 认证服务
     * @param userService 人员信息服务
     * @param loginLogService 登录日志服务
     * @param partyService 党员信息相关服务
     * @return FilterRegistrationBean 过滤器
     */
    @Bean
    public FilterRegistrationBean<SecurityFilter> registerSecurityFilter(final ResourceService resourceService,
                                                                         final RoleService roleService,
                                                                         final RestTemplate restTemplate,
                                                                         final AuthService authService,
                                                                         final UserService userService,
                                                                         final LoginLogService loginLogService,
                                                                         final PartyService partyService,
                                                                         final PurviewService purviewService) {
        final FilterRegistrationBean<SecurityFilter> bean = new FilterRegistrationBean<>();
        bean.setOrder(SECURITY_FILTER_ORDER);
        final SecurityFilter filter = new SecurityFilter(resourceService, roleService,
                restTemplate, accessToken, getUserUrl, authService, userService, purviewService);
        filter.setDemo(demo);
        filter.setLoginLogService(loginLogService);
        filter.setPartyService(partyService);
        bean.setFilter(filter);
        bean.addUrlPatterns("/*");
        return bean;
    }

    /**
     * 监控filter.
     * @return
     */
    @Bean
    public FilterRegistrationBean<PerformanceMonitorFilter> registerMonitorFilter(final PerformanceMonitorMapper performanceMonitorMapper) {
        final FilterRegistrationBean<PerformanceMonitorFilter> bean = new FilterRegistrationBean<>();
        bean.setOrder(MONITOR_FILTER_ORDER);
        final PerformanceMonitorFilter filter = new PerformanceMonitorFilter(performanceMonitorMapper);
        bean.setFilter(filter);
        bean.addUrlPatterns("/*");
        return bean;
    }
}
